package org.aldar.bquest.entity.effect;

import org.aldar.bquest.entity.pool.TilesPool;
import org.aldar.bquest.screens.MainBoardScreen;
import org.andengine.engine.Engine;
import org.andengine.entity.Entity;
import org.andengine.entity.IEntity;
import org.andengine.entity.modifier.IEntityModifier;
import org.andengine.entity.modifier.MoveModifier;
import org.andengine.entity.sprite.Sprite;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.util.modifier.IModifier;

import java.util.Random;

/**
 * User: Daria
 * Date: 7/23/14 11:05 AM
 */
public class ParticleEmitter {

    private Entity layerToAttach;
    private Engine engine;
    private int particlesCount;

    private int radius;

    private float duration;

    private float startX;

    private float startY;

    private ITextureRegion textureRegion;

    private float particleAlpha = 1;

    public ParticleEmitter(int particlesCount, int radius, float duration, float startX, float startY, ITextureRegion textureRegion, Engine engine, Entity layerToAttach) {
        this.particlesCount = particlesCount;
        this.radius = radius;
        this.duration = duration;
        this.startX = startX;
        this.startY = startY;
        this.textureRegion = textureRegion;
        this.engine = engine;
        this.layerToAttach = layerToAttach;
    }

    public ParticleEmitter(int particlesCount, int radius, float duration, float startX, float startY, float alpha, ITextureRegion textureRegion, Engine engine, Entity layerToAttach) {
        this(particlesCount, radius, duration, startX, startY, textureRegion, engine, layerToAttach);
        this.particleAlpha = alpha;
    }

    public ParticleEmitter(int particlesCount, int radius, float duration, float startX, float startY, float alpha, ITextureRegion textureRegion) {
        this(particlesCount, radius, duration, startX, startY, textureRegion, MainBoardScreen.getInstanceEngine(), MainBoardScreen.getScm().getTestLayer());
        this.particleAlpha = alpha;
    }

    public ParticleEmitter(int particlesCount, int radius, float duration, float startX, float startY, ITextureRegion textureRegion) {
        this(particlesCount, radius, duration, startX, startY, textureRegion, MainBoardScreen.getInstanceEngine(), MainBoardScreen.getScm().getBonusLayer());
    }

    public void start() {
        for (int i = 0; i < particlesCount; i++) {
            final Sprite particleSprite = TilesPool.getEntityForTexture(textureRegion, engine.getVertexBufferObjectManager());
            particleSprite.setPosition(startX, startY);

            float endCoordX = startX + new Random().nextInt(radius * 2) - radius;
            float endCoordY = startY + new Random().nextInt(radius * 2) - radius;

            //particleSprite.setAnchorCenter(0, 0);
            particleSprite.setScale(1f);
            particleSprite.setAlpha(particleAlpha);
            layerToAttach.attachChild(particleSprite);
            final int finalI = i;
            particleSprite.registerEntityModifier(new MoveModifier(duration, startX, startY, endCoordX, endCoordY, new IEntityModifier.IEntityModifierListener() {
                @Override
                public void onModifierStarted(IModifier<IEntity> pModifier, IEntity pItem) {
                }

                @Override
                public void onModifierFinished(IModifier<IEntity> pModifier, IEntity pItem) {
                    engine.runOnUpdateThread(new Runnable() {
                        @Override
                        public void run() {
                            particleSprite.detachSelf();
                            TilesPool.pushEntityToStack(particleSprite);
                        }
                    });
                }
            }) {
                @Override
                protected void onManagedUpdate(float pSecondsElapsed, IEntity pItem) {
                    super.onManagedUpdate(pSecondsElapsed, pItem);
                    float percentage = getSecondsElapsed() / getDuration();
                    if (particleAlpha != 1) {
                        particleSprite.setAlpha(particleAlpha);
                    } else if (percentage > 0.5) {
                        particleSprite.setAlpha((1 - (percentage - 0.5f) * 2) * particleAlpha);
                    }
                }
            });
        }
    }
}
